#include "stdafx.h"
#include "Sender.h"
#include <sstream>

CSender* CSender::m_Instance = NULL;

CSender::CSender(void)
{

}

CSender::~CSender(void)
{
}

CSender* CSender::getInstance(void)
{
	return m_Instance;
}

void CSender::createInstance(void)
{
	if( m_Instance == NULL )
	{
		m_Instance = new CSender;
		CSender::getInstance()->initialize();
	}
}
void CSender::destroy(void)
{
	if( m_Instance != NULL)
	{
		delete m_Instance;
	}
}

void CSender::initialize(void)
{
	m_mEnv.clear();
	m_mRoom.clear();
	m_mEndgameid.clear();
	m_mMid.clear();
	m_mTurnOverid.clear();
	m_mUserID.clear();
}

void CSender::initializeRoom(jint roomId)
{
	
}

void CSender::renew(JNIEnv* env, jobject room, jint roomId)
{
	jclass jcl;

	if( m_mEnv.find(roomId) == m_mEnv.end() )
	{
		typedef pair<jint, JNIEnv*> pair_env;
		m_mEnv.insert( pair_env(roomId, NULL) );
	}

	if( m_mRoom.find(roomId) == m_mRoom.end() )
	{
		typedef pair<jint, jobject> pair_room;
		m_mRoom.insert( pair_room(roomId, NULL) );
	}

	if( m_mEndgameid.find(roomId) == m_mEndgameid.end() )
	{
		typedef pair<jint, jmethodID> pair_id;
		m_mEndgameid.insert( pair_id(roomId, NULL) );
	}

	if( m_mMid.find(roomId) == m_mMid.end() )
	{
		typedef pair<jint, jmethodID> pair_id;
		m_mMid.insert( pair_id(roomId, NULL) );
	}

	if( m_mTurnOverid.find(roomId) == m_mTurnOverid.end() )
	{
		typedef pair<jint, jmethodID> pair_id;
		m_mTurnOverid.insert( pair_id(roomId, NULL) );
	}

	m_mEnv[roomId] = env;
	m_mRoom[roomId] = room;
	jcl = m_mEnv.find(roomId)->second->GetObjectClass(room);
	m_mEndgameid[roomId] = m_mEnv.find(roomId)->second->GetMethodID(jcl, "processEndGame", "()V");
	m_mMid[roomId] = m_mEnv.find(roomId)->second->GetMethodID(jcl, "broadcastPacket", "(Ljava/lang/String;)V");
	m_mTurnOverid[roomId] = m_mEnv.find(roomId)->second->GetMethodID(jcl, "turnOver", "(I)V");
}

void CSender::setUserID(jint roomId, int userSlot, int userID)
{
	if( m_mUserID.find(roomId) == m_mUserID.end() )
	{
		typedef pair<jint, int*> arr_pair;
		m_mUserID.insert( arr_pair(roomId, new int[5]));
		for(int i = 0; i < 5; i++)
		{
			(m_mUserID.find(roomId)->second)[i] = -999;
		}
	}
	(m_mUserID.find(roomId)->second)[userSlot] = userID;
}


void CSender::destroyRoom(jint roomId)
{

	if( m_mEnv.find(roomId) != m_mEnv.end() ) //
		m_mEnv.erase(roomId);

	if( m_mRoom.find(roomId) != m_mRoom.end() ) //
		m_mRoom.erase(roomId);

	if( m_mEndgameid.find(roomId) != m_mEndgameid.end() ) //
		m_mEndgameid.erase(roomId);

	if( m_mMid.find(roomId) != m_mMid.end() ) //
		m_mMid.erase(roomId);

	if( m_mTurnOverid.find(roomId) != m_mTurnOverid.end() ) //
		m_mTurnOverid.erase(roomId);
	
	if( m_mUserID.find(roomId) != m_mUserID.end() )
	{
		delete m_mUserID.find(roomId)->second;
		m_mUserID.erase(roomId);
	}

}

void CSender::setPacket(EVENTTYPE eventtype, vector<int> vChplist, int userSlot, jint roomId)
{
	string str;
	ostringstream ostr;
	unsigned int size = vChplist.size();

	switch(eventtype)
	{
	case Asset_event:
		str += "EPACKET_IC_ASSET ";
		break;
	case Merge_event:
		str += "EPACKET_IC_MERGE ";
		break;
	case President_event:
		str += "EPACKET_IC_PRESIDENT ";
		break;
	case Chairman_event:
		str += "EPACKET_IC_CHAIRMAN ";
		break;
	}

	ostr<<size<<" ";

	for(unsigned int i = 0; i < size; i++)
	{
		ostr<<vChplist[i]<<" ";
	}

	ostr<<(m_mUserID.find(roomId)->second)[userSlot];

	str += ostr.str();

	sendMessage(str, roomId);
	if( eventtype == Chairman_event )
	{
		//process over;
		//sendGameover(roomId);
	}
}

void CSender::sendMessage(string str, jint roomId)
{
	cout<<"[PACKET]"<<str<<endl;
	if(m_mEnv.find(roomId) != m_mEnv.end())
	{
		if( m_mEnv.find(roomId)->second != NULL )
		{
			jstring jstrBuf = m_mEnv.find(roomId)->second->NewStringUTF(str.c_str());
			m_mEnv.find(roomId)->second->CallVoidMethod(m_mRoom.find(roomId)->second, m_mMid.find(roomId)->second, jstrBuf);
		}
		else
		{
			cout<<"]![ERROR:sendMessage]Env NULL!"<<endl;
		}
	}
	else
	{
		cout<<"]![ERROR:sendMessage]There is no Env assoicated with room."<<endl;
	}
	
	
}

void CSender::sendTurnover(int userSlot, jint roomId)
{
	if(m_mEnv.find(roomId) != m_mEnv.end())
	{
		if( m_mEnv.find(roomId)->second != NULL )
		{
			m_mEnv.find(roomId)->second->CallVoidMethod(m_mRoom.find(roomId)->second, m_mTurnOverid.find(roomId)->second, userSlot);
		}
		else
		{
			cout<<"]![ERROR:sendTurnover]Env NULL!"<<endl;
		}
	}
	else
	{
		cout<<"]![ERROR:sendTurnover]There is no Env assoicated with room."<<endl;
	}
}

void CSender::sendGameover(jint roomId)
{
	if(m_mEnv.find(roomId) != m_mEnv.end())
	{
		if( this->m_mEnv.find(roomId)->second != NULL )
		{
			m_mEnv.find(roomId)->second->CallVoidMethod( m_mRoom.find(roomId)->second, m_mEndgameid.find(roomId)->second);
		}
		else
		{
			cout<<"]![ERROR:sendGameover]Env NULL!"<<endl;
		}
	}
	else
	{
		cout<<"]![ERROR:sendGameover]There is no Env assoicated with room."<<endl;
	}
}

void CSender::printSomething(void)
{

}